using System;

namespace Sagile.Nepma
{
    /// <summary>
    /// This interface defines all methods for handling multiple task processing.
    /// It contains methods for adding and removing tasks and groups of tasks.
    /// Multiple methods are defined for starting and stopping tasks.
    /// </summary>
    public interface ITaskManager : IExceptionReporter
    {
        #region Properties

        /// <summary>
        /// Gets or sets a value indicating whether process must pause when an error occurs.
        /// </summary>
        /// <value><c>true</c> if [pause on error]; otherwise, <c>false</c>.</value>
        bool PauseOnError { get; set; }

        /// <summary>
        /// Gets the running tasks count.
        /// </summary>
        /// <value>The running tasks count.</value>
        int RunningTasksCount { get; }

        /// <summary>
        /// Gets the finished tasks count.
        /// </summary>
        /// <value>The finished tasks count.</value>
        int FinishedTasksCount { get; }
        
        /// <summary>
        /// Gets the aborted tasks count.
        /// </summary>
        /// <value>The aborted tasks count.</value>
        int AbortedTasksCount { get; }
        
        /// <summary>
        /// Gets the remaining tasks count.
        /// </summary>
        /// <value>The remaining tasks count.</value>
        int RemainingTasksCount { get; }

        /// <summary>
        /// Gets the tasks count.
        /// </summary>
        /// <value>The tasks count.</value>
        int TasksCount { get; }

        #endregion Properties

        #region Events

        /// <summary>
        /// Occurs when tasks are processed
        /// </summary>
        event EventHandler<EventArgs> Completed;

        /// <summary>
        /// Occurs when processing is started
        /// </summary>
        event EventHandler<EventArgs> Started;

        /// <summary>
        /// Occurs when a task has started.
        /// </summary>
        event EventHandler<ManageableTaskEventArgs> TaskStarted;
        
        /// <summary>
        /// Occurs when a start has finished.
        /// </summary>
        event EventHandler<ManageableTaskEventArgs> TaskCompleted;
        
        /// <summary>
        /// Occurs when a task has aborted.
        /// </summary>
        event EventHandler<ManageableTaskEventArgs> TaskAborted;

        #endregion Events

        #region Adding task(s)

        /// <summary>
        /// Adds the task.
        /// </summary>
        /// <param name="task">The task.</param>
        void AddTask(ISequenceTask task);

        /// <summary>
        /// Adds the group of tasks.
        /// </summary>
        /// <param name="group">The group.</param>
        void AddGroup(ISequenceTask[] group);

        #endregion Adding task(s)

        #region Removing task(s)

        /// <summary>
        /// Removes the task.
        /// </summary>
        /// <param name="task">The task.</param>
        void RemoveTask(ISequenceTask task);

        /// <summary>
        /// Removes the group.
        /// </summary>
        /// <param name="group">The group.</param>
        void RemoveGroup(ISequenceTask[] group);

        /// <summary>
        /// Clears all tasks.
        /// </summary>
        void ClearTasks();

        #endregion Removing task(s)

        #region Starting task(s)

        /// <summary>
        /// Starts the sequence.
        /// </summary>
        void StartSequence();
        /// <summary>
        /// Starts the next group.
        /// </summary>
        void StartNextGroup();
        /// <summary>
        /// Starts the next task.
        /// </summary>
        void StartNextTask();

        #endregion Starting task(s)

        #region Stopping task(s)

        /// <summary>
        /// Stops the sequence.
        /// </summary>
        void StopSequence();
        /// <summary>
        /// Stops the current group.
        /// </summary>
        void StopCurrentGroup();
        /// <summary>
        /// Stops the current task.
        /// </summary>
        void StopCurrentTask();

        #endregion Stopping task(s)
    }
}
